<?php
namespace App\Service\ApiQd;

use App\Service\Admin\ImageService;
use Illuminate\Support\Facades\DB;

class UserService extends BaseService
{
    protected $app_id = 'wxad7c7696f8810af0';//'wxbf3d9e70e4eb9fb0';
    protected $app_secret = 'e1e6f0965adada4a07b3bdae474a17a3';//'65df5b844267bf0c8624758557b8ccc7';
    //用户

    /**
     * 保存用户信息
     * @param array $pas
     * @return array
     */
    public function saveWxInfo($pas, $uid)
    {
        $uData = [
            'lasttime' => toDate(),
            'uptime' => toDate(),
        ];
        if(!empty($pas['phone'])){
            $uData['phone'] = $pas['phone'];
        }
        if(!empty($pas['nickname'])){
            $uData['nickname'] = $pas['nickname'];
        }
        if(!empty($pas['avatarUrl'])){
            $uData['avatarUrl'] = $pas['avatarUrl'];
        }
        $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->update($uData);
        return array('code' => 0, 'msg' => 'success');
    }

    /**
     * 保存用户信息
     * @param array $pas
     * @return array
     */
    public function wxByOpenid($pas)
    {
        $wxOne = (array) $this->dbwbConn($this->dbDistributorUser)->where('openid', $pas['openid'])->first();

        if (empty($wxOne)) {
            $nick = $pas['nickname'] ? $pas['nickname'] : time().rand(10000, 99999);
            $token = toToken();
            $uData = [
                'openid' => $pas['openid'],
                'parent_id' => $pas['parent_id'],
                'nickname' => $nick,
                'avatarUrl' => $pas['avatarUrl'],
                'serial' => toUserno(),
                'token' => $token,
                'wxjson' => json_encode($pas, JSON_UNESCAPED_UNICODE),
                'addtime' => toDate(),
                'lasttime' => toDate(),
            ];
            $this->dbwbConn($this->dbDistributorUser)->insertGetId($uData);
        } else {
            $uData = [
                'wxjson' => json_encode($pas, JSON_UNESCAPED_UNICODE),
                'lasttime' => toDate(),
            ];
            if($wxOne['parent_id'] == 0) {
                $uData['parent_id'] = $pas['parent_id'];
            }
            if (!$wxOne['serial']) $uData['serial'] = toUserno();
            $this->dbwbConn($this->dbDistributorUser)->where('id', $wxOne['id'])->update($uData);
            $token = $wxOne['token'];
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $token);
    }

    /**
     * 上传头像
     * @param int $uid
     * @param array $imgs【imglink，w，h】
     */
    public function setHead($uid, $imgs)
    {
        $imglink = $imgs['link'];
        (new ImageService())->addOne($imglink, $imgs['w'], $imgs['h']);
        $uOne = (array) $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return array('code' => -2, 'msg' => '该用户不存在');
        }
        $uData = [
            'avatarUrl' => $imglink,
            'uptime' => toDate(),
        ];
        $res = $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->update($uData);
        if (!$res) {
            return array('code' => -1, 'msg' => 'error');
        }
        return array('code' => 0, 'msg' => 'success');
    }

    /**
     * 上传推广二维码
     * @param int $uid
     * @param array $imgs【imglink，w，h】
     */
    public function setQR($uid, $imgs)
    {
        $imglink = $imgs['link'];
        (new ImageService())->addOne($imglink, $imgs['w'], $imgs['h']);
        $uOne = (array) $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return array('code' => -2, 'msg' => '该用户不存在');
        }
        $uData = [
            'qr_image' => $imglink,
            'uptime' => toDate(),
        ];
        $res = $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->update($uData);
        if (!$res) {
            return array('code' => -1, 'msg' => 'error');
        }
        return array('code' => 0, 'msg' => 'success');
    }

    /**
     * 上传推广海报
     * @param int $uid
     * @param array $imgs【imglink，w，h】
     */
    public function setPoster($uid, $imgs)
    {
        $imglink = $imgs['link'];
        (new ImageService())->addOne($imglink, $imgs['w'], $imgs['h']);
        $uOne = (array) $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return array('code' => -2, 'msg' => '该用户不存在');
        }
        $uData = [
            'poster' => $imglink,
            'uptime' => toDate(),
        ];
        $res = $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->update($uData);
        if (!$res) {
            return array('code' => -1, 'msg' => 'error');
        }
        return array('code' => 0, 'msg' => 'success');
    }

    /**
     * 海报合成
     * @param int $uid
     * @param array $imgs【imglink，w，h】
     */
    public function conflatePoster($user_info)
    {
        if($user_info['poster']){
            return array('code' => 0, 'msg' => 'success', 'data' => $user_info['poster']);
        }
        $qrCodePath = $user_info['qr_image'];
        $compressedQrCodePath = '';
        if (empty($qrCodePath)) {
            // 生成微信小程序二维码
            $appId = $this->app_id; // 替换为您的小程序AppID
            $appSecret = $this->app_secret; // 替换为您的小程序AppSecret
            $page = 'pages/index/index'; // 小程序页面路径
            $scene = 'user_id=' . $user_info['id']; // 传递的参数
            // 获取access_token
            $accessToken = $this->getAccessToken($appId, $appSecret);
            if (!$accessToken) {
                return array('code' => -1, 'msg' => '获取access_token失败');
            }
            // 生成小程序二维码
            $qrCodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken}";
            $postData = json_encode([
                'scene' => $scene,
                'page' => $page,
                'width' => 100,
            ]);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $qrCodeUrl);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
            ]);
            $qrCodeImage = curl_exec($ch);
            curl_close($ch);
            // 保存二维码
            $qrCodePath = 'upload/qrcodes/user_' . $user_info['id'] . '.png';
            file_put_contents($qrCodePath, $qrCodeImage);
            // 创建图像资源并压缩二维码到 100x100
            $qrCodeImageResource = imagecreatefromstring($qrCodeImage); // 从字符串创建图像资源
            $scaledImage = imagecreatetruecolor(100, 100); // 创建 100x100 的新图像
            // 将二维码缩放到 100x100
            imagecopyresampled($scaledImage, $qrCodeImageResource, 0, 0, 0, 0, 100, 100, imagesx($qrCodeImageResource), imagesy($qrCodeImageResource));
            // 保存压缩后的二维码
            $compressedQrCodePath = 'upload/qrcodes/compressed_user_' . $user_info['id'] . '.png';
            imagepng($scaledImage, $compressedQrCodePath); // 保存压缩后的二维码
            // 释放内存
            imagedestroy($qrCodeImageResource);
            imagedestroy($scaledImage);
            $uData = [
                'qr_image' => $compressedQrCodePath,
                'uptime' => toDate(),
            ];
            $this->dbwbConn($this->dbDistributorUser)->where('id', $user_info['id'])->update($uData);
        }
        $bg = 'images/posterbg2.png';
        // Check if background image exists
        if (!file_exists($bg)) {
            return array('code' => -1, 'msg' => '背景图片不存在');
        }
        if (!$compressedQrCodePath) {
            return $this->toback(-2, '没有背景图');
        }
        // Create image resources
        $background = imagecreatefrompng($bg);
        $qr_code = imagecreatefromstring(file_get_contents($compressedQrCodePath));
        // Get image dimensions
        $bg_width = imagesx($background);
        $bg_height = imagesy($background);
        $qr_width = imagesx($qr_code);
        $qr_height = imagesy($qr_code);
        // Calculate position to place QR code (bottom right corner with 20px margin)
        $qr_x = $bg_width - $qr_width - 135;
//        $qr_y = $bg_height - $qr_height - 85;
        $qr_y = $bg_height - $qr_height - 100;
        // Merge images
        imagecopy($background, $qr_code, $qr_x, $qr_y, 0, 0, $qr_width, $qr_height);
        $timestamp = time();
        $uploadDir = 'upload/' . date('Ymd', $timestamp);
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true); // Create directory if it doesn't exist
        }
        // Save the merged image in the new directory
        $output_file = $uploadDir . '/merged_poster' . $user_info['id'] .'_' . $timestamp . '.png';
        imagepng($background, $output_file);
        // Free up memory
        imagedestroy($background);
        imagedestroy($qr_code);
        return array('code' => 0, 'msg' => 'success', 'data' => $output_file);
    }

    /**
     * 获取access_token
     * @param string $appId
     * @param string $appSecret
     * @return string|null
     */
    private function getAccessToken($appId, $appSecret)
    {
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
        $response = file_get_contents($url);
        $data = json_decode($response, true);
        return isset($data['access_token']) ? $data['access_token'] : null;
    }

    /**
     * 上传头像
     * @param int $uid
     * @param string $nick
     */
    public function setNick($uid, $nick)
    {
        $uOne = (array) $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return array('code' => -2, 'msg' => '该用户不存在');
        }
        $uData = [
            'nickname' => $nick,
            'uptime' => toDate(),
        ];
        $res = $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->update($uData);
        if (!$res) {
            return array('code' => -1, 'msg' => 'error');
        }
        return array('code' => 0, 'msg' => 'success');
    }

    /**
     * 修改手机号
     * @param int $uid
     * @param string $phone
     */
    public function setPhone($uid, $phone)
    {
        $uOne = (array) $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return array('code' => -2, 'msg' => '该用户不存在');
        }
        $uData = [
            'phone' => $phone,
            'uptime' => toDate(),
        ];
        $res = $this->dbwbConn($this->dbDistributorUser)->where('id', $uid)->update($uData);
        if (!$res) {
            return array('code' => -1, 'msg' => 'error');
        }
        return array('code' => 0, 'msg' => 'success');
    }

    /**
     * 领取优惠劵
     * @param int $uid
     */
    public function addCouponByNew($uid)
    {
        $total = $this->dbConn($this->dbUcoupon)
            ->where('type', 1)
            ->where('uid', $uid)
            ->count();
        if ($total) {
            return array('code' => -2, 'msg' => '该用户已领取');
        }
        $tmpOnes = $this->dbConn($this->dbUcouponTmp)
            ->where('del', 0)
            ->where('type', 1)
            ->get();
        if (!count($tmpOnes)) {
            return array('code' => -2, 'msg' => '新用户优惠劵未设置');
        }
        $arys = [];
        foreach ($tmpOnes as $v) {
            $v = (array) $v;
            //有效期
            $expire = time() + $v['expire'] * 3600 * 24;
            $expire = date('Y-m-d H:i:s', $expire);
            $arys[] = [
                'uid' => $uid,
                'quata' => $v['quata'],
                'scene' => $v['scene'],
                'full' => $v['full'],
                'reduce' => $v['reduce'],
                'expire' => $expire,
                'addtime' => toDate(),
            ];
        }
        if (!count($arys)) {
            return array('code' => -2, 'msg' => '新用户优惠劵失败');
        }
        DB::beginTransaction(); //开启事务
        try {
            foreach ($arys as $v) {
                $lastid = $this->dbConn($this->dbUcoupon)->insertGetId($v);
                if (!$lastid) {
                    return array('code' => -2, 'msg' => '领取失败');
                }
            }
            DB::commit(); //提交事务
            return array('code'=>0, 'msg'=>'success');
        } catch (\Exception $e) {
            DB::rollBack(); //事务回滚
            echo $e->getMessage();
            return array('code'=>-1, 'msg'=>'操作失败');
        }
    }

    //等级列表
    public function getLevelList()
    {
        $res = $this->dbConn($this->dbUlevel)
            ->where('del', 0)
            ->get();
        if (!count($res)) {
            return array('code' => 0, 'msg' => '没有数据', 'data' => [], 'total' => 0);
        }
        $arys = [];
        foreach ($res as $v) {
            $v = (array) $v;
            $icon = file_exists($v['icon']) ? env('DOMAIN').'/'.$v['icon'] : '';
            $arys[] = [
                'id' => $v['id'],
                'title' => $v['title'],
                'describe' => $v['describe'],
                'icon' => $icon,
                'price' => $v['price'] / 100,
            ];
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $arys, 'total' => count($arys));
    }

    //充值记录列表
    public function getRechargeList($pages, $uid)
    {
        $start = ($pages['page'] - 1) * $pages['size'];
        $db = $this->dbwbConn($this->dbDistributorPay, ['type' => 1, 'status' => 2, 'uid' => $uid]);
        $total = $db->count();
        $res = $db->skip($start)->take($pages['size'])
            ->select('addtime', 'money', 'balance')
            ->get();
        if (!count($res)) {
            return array('code' => 0, 'msg' => 'success', 'data' => [], 'total' => $total);
        }
        $arys = [];
        foreach ($res as $v) {
            $v = (array) $v;
            $arys[] = [
                'title' => '充值成功',
                'addtime' => $v['addtime'],
                'money' => toNumber($v['money']),
                'balance' => toNumber($v['balance']),
            ];
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $arys, 'total' => $total);
    }

    //获取用户信息
    public function getOneByToken($token)
    {
        $res = (array) $this->dbwbConn($this->dbDistributorUser)
            ->where('token', $token)
            ->first();
        if (empty($res)) {
            return array('code' => -2, 'msg' => '用户不存在');
        }
        if (!$res['serial']) {
            $serial = $res['serial'] = toUserno();
            $this->dbwbConn($this->dbDistributorUser)->where('id', $res['id'])->update(['serial' => $serial]);
        }
        $res['balance'] = $res['balance'] / 100;
        if (substr($res['avatarUrl'], 0, 4) != 'http') {
            $res['avatarUrl'] = $res['avatarUrl'] ? env('DOMAIN') . '/' . $res['avatarUrl'] : '';
        }
        $res['version'] = 'V1.0';
        //待付款的
        $res['orderPayNum'] = $this->dbwbConn($this->dbDistributorOrder)
            ->where('iscancel', 1)
            ->where('uid', $res['id'])
            ->where('status', 1)
            ->count();
        $res['orderSendNum'] = $this->dbwbConn($this->dbDistributorOrder)
            ->where('iscancel', 1)
            ->where('uid', $res['id'])
            ->where('delivery', 1)
            ->where('status', 2)
            ->count();
        $res['orderAcceptNum'] = $this->dbwbConn($this->dbDistributorOrder)
            ->where([
                ['iscancel', '=', 1],
                ['uid', '=', $res['id']],
                ['delivery', '=', 1],
                ['status', '=', 3],
            ])
            ->orWhere([
                ['iscancel', '=', 1],
                ['uid', '=', $res['id']],
                ['delivery', '=', 2],
                ['status', '=', 2],
            ])
            ->count();
        $res['orderCancelNum'] = $this->dbwbConn($this->dbDistributorOrder)
            ->where('uid', $res['id'])
            ->where('iscancel', 2)
            ->where('status', 4)
            ->count();
        $res['bond'] = toNumber($res['bond']);
        return array('code' => 0, 'msg' => 'success', 'data' => $res);
    }

    //获取团队列表
    public function getTeamList($pages, $uid)
    {
        $start = ($pages['start'] - 1) * $pages['limit'];
        $db = $this->dbwbConn($this->dbDistributorUser)->where('parent_id', $uid);
        $total = $db->count();
        $res = $db->skip($start)->take($pages['limit'])
            ->orderBy('id', 'desc')
            ->get()
            ->map(function ($value){
                return (array)$value;
            })
            ->toArray();
        return array('code' => 0, 'msg' => 'success', 'data' => $res, 'total' => $total);
    }

    //获取团队订单列表
    public function getTeamOrderList($pages, $uid)
    {
        $start = ($pages['start'] - 1) * $pages['limit'];
        $db = $this->dbwbConn($this->dbDistributorOrder . ' as o')
            ->leftJoin($this->dbDistributorUser . ' as u', 'u.id', '=', 'o.uid')
            ->where('u.parent_id', $uid);
        $total = $db->count();
        $res = $db->skip($start)->take($pages['limit'])
            ->select('o.id', 'o.orderno', 'u.phone', 'u.avatarUrl', 'o.uname', 'o.addtime')
            ->orderBy('id', 'desc')
            ->get()
            ->map(function ($value){
                return (array)$value;
            })
            ->toArray();
        return array('code' => 0, 'msg' => 'success', 'data' => $res, 'total' => $total);
    }

    //获取团队订单统计
    public function getTeamOrderCount($uid)
    {
        $total = $this->dbwbConn($this->dbDistributorOrder . ' as o')
            ->leftJoin($this->dbDistributorUser . ' as u', 'u.id', '=', 'o.uid')
            ->where('u.parent_id', $uid)
            ->count();
        $today_time = toToday();
        $today = $this->dbwbConn($this->dbDistributorOrder . ' as o')
            ->leftJoin($this->dbDistributorUser . ' as u', 'u.id', '=', 'o.uid')
            ->where('u.parent_id', $uid)
            ->whereBetween('o.addtime', [$today_time['start'], $today_time['end']])
            ->count();
        $month_time = toMonth();
        $month = $this->dbwbConn($this->dbDistributorOrder . ' as o')
            ->leftJoin($this->dbDistributorUser . ' as u', 'u.id', '=', 'o.uid')
            ->where('u.parent_id', $uid)
            ->whereBetween('o.addtime', [$month_time['start'], $month_time['end']])
            ->count();
        $res = [
            'all' => $total,
            'today' => $today,
            'month' => $month
        ];
        return array('code' => 0, 'msg' => 'success', 'data' => $res);
    }

    //会员充值
    public function rechargeList()
    {
        $res = $this->db2Conn($this->dbEqCost)
            ->select('id', 'cost')
            ->where('del', 0)
            ->where('type', 1)
            ->get();
        if (!count($res)) {
            return $this->toback(-2, '没有记录');
        }
        $arys = [];
        foreach ($res as $v) {
            $v = (array) $v;
            $arys[] = [
                'id' => $v['id'],
                'cost' => toNumber($v['cost']),
            ];
        }
        return $this->toback(0, '', $arys);
    }

    //保证金
    public function bondList()
    {
        $res = $this->db2Conn($this->dbEqCost)
            ->select('id', 'cost')
            ->where('del', 0)
            ->where('type', 2)
            ->get();
        if (!count($res)) {
            return $this->toback(-2, '没有记录');
        }
        $arys = [];
        foreach ($res as $v) {
            $v = (array) $v;
            $arys[] = [
                'id' => $v['id'],
                'cost' => toNumber($v['cost']),
            ];
        }
        return $this->toback(0, '', $arys);
    }
}